package com.torresquintero.oncologos.medico.controlador;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;

import com.torresquintero.oncologos.common.factory.FactoryEntityManager;
import com.torresquintero.oncologos.entidades.Articulo;
import com.torresquintero.oncologos.entidades.Consulta;
import com.torresquintero.oncologos.entidades.DetalleFormulaMedica;
import com.torresquintero.oncologos.entidades.DetalleHistoriaClinica;
import com.torresquintero.oncologos.entidades.DetalleOrdenMedica;
import com.torresquintero.oncologos.entidades.FormulaMedica;
import com.torresquintero.oncologos.entidades.HistoriaClinica;
import com.torresquintero.oncologos.entidades.OrdenMedica;
import com.torresquintero.oncologos.entidades.Paciente;
import com.torresquintero.oncologos.entidades.Procedimiento;
import com.torresquintero.oncologos.enumeraciones.EstadoConsultaEnum;

/**
 * Controlador de la atencion a Consultas.
 * 
 * @author Camilo Andres
 * 
 */
@SuppressWarnings("unchecked")
public class AtenderConsultaController {

    /**
     * Variable statica para el partron Singleton
     */
    private static AtenderConsultaController atenderControladorConsultas;
    /**
     * Administrador de entidades.
     */
    private EntityManager em;
    /**
     * Orden de la consulta
     */
    private OrdenMedica orden;
    /**
     * Formula medica de la consulta.
     */
    private FormulaMedica formula;
    /**
     * Consulta donde se agregara todo.
     */
    private Consulta consulta;
    /**
     * Paciente de la Consulta.
     */
    private Paciente paciente;
    /**
     * Historia Clinica del paciente
     */
    private HistoriaClinica historiaClinica;
    private DetalleHistoriaClinica detalleHistoria;

    /**
     * Constructor, inicializa el EntityManager.
     */
    
    public AtenderConsultaController(long idConsulta){
         em = FactoryEntityManager.getEm();
         
         consulta=em.find(Consulta.class, idConsulta);
         
         
          /* Inicializando la Orden Medica. */
        orden = new OrdenMedica();
        List<DetalleOrdenMedica> listaDet = new ArrayList<DetalleOrdenMedica>();
        orden.setDetalleOrdenMedica(listaDet);

        /* Inicializando la FOrmula Medica. */
        List<DetalleFormulaMedica> detalleFormula = new ArrayList<DetalleFormulaMedica>();
        formula = new FormulaMedica();
        formula.setDetallesFormulaMedica(detalleFormula);
        
        setConsulta(consulta);
         
         
    }
    
    private AtenderConsultaController() {

        em = FactoryEntityManager.getEm();

        /* Inicializando la Orden Medica. */
        orden = new OrdenMedica();
        List<DetalleOrdenMedica> listaDet = new ArrayList<DetalleOrdenMedica>();
        orden.setDetalleOrdenMedica(listaDet);

        /* Inicializando la FOrmula Medica. */
        List<DetalleFormulaMedica> detalleFormula = new ArrayList<DetalleFormulaMedica>();
        formula = new FormulaMedica();
        formula.setDetallesFormulaMedica(detalleFormula);
    }

    /**
     * Metodo para obtener una instancia singleton de esta clase.
     * 
     * @return
     */
    public static AtenderConsultaController getInstance() {

        if (atenderControladorConsultas == null) {
            atenderControladorConsultas = new AtenderConsultaController();
        }
        return atenderControladorConsultas;
    }

    /**
     * Metodo para agregar un articulo a la formula medica.
     * 
     * @param articulo
     *            articulo a aagregar.
     * @param cantidad
     *            cantidad del articulo
     * @param prescripcion
     *            comentario del medico de acuerdo a la posologia.
     */
    public void agregarMedicamentoFormula(Articulo articulo, int cantidad,
            String prescripcion) {

        DetalleFormulaMedica det = new DetalleFormulaMedica();
        det.setArticulo(articulo);
        det.setCantidad(cantidad);
        det.setFormulaMedica(formula);
        det.setPrescripcion(prescripcion);
        formula.getDetallesFormulaMedica().add(det);
    }
    
    /**
     * Metodo para quitar un medicamento de la formula.
     */
    public void quitarMedicamentoFormula(int pos){
        formula.getDetallesFormulaMedica().remove(pos);
    }

    /**
     * Metodo para agregar un procedimiento a la consulta activa.
     * 
     * @param procedimiento
     * @param cantidad
     * @param observacion
     */
    public void agregarProcedimiento(Procedimiento procedimiento, int cantidad,
            String observacion) {

        DetalleOrdenMedica det = new DetalleOrdenMedica();
        det.setCantidad(cantidad);
        det.setObservacion(observacion);
        det.setOrdenMedica(orden);
        det.setProcedimiento(procedimiento);
        orden.getDetalleOrdenMedica().add(det);
    }
    
    /**
     * Metodo para quitar un medicamento de la formula.
     */
    public void quitarProcedimiento(int pos){
        orden.getDetalleOrdenMedica().remove(pos);
    }

    /**
     * metodo para ver la historia clinica del paciente.
     * @return Historia clinica.
     */
    public HistoriaClinica verHistoriaClinicaPaciente() {
        historiaClinica = (HistoriaClinica) em.createNamedQuery(HistoriaClinica.FIND_HISTORIA_CLINICA_BY_NUMERO_Y_TIPO_DOCUMENTO_PACIENTE).
                setParameter(HistoriaClinica.PARAMETRO_NUMERO_DOCUMENTO_PACIENTE, paciente.getDocumento()).
                setParameter(HistoriaClinica.PARAMETRO_TIPO_DOCUMENTO_PACIENTE, paciente.getTipoDocumento()).
                getSingleResult();

        List<DetalleHistoriaClinica> detHis = em.createNamedQuery(DetalleHistoriaClinica.FIND_DETALLE_HISTORIA_CLINICA_BY_ID_HISTORIA_CLINICA).setParameter(DetalleHistoriaClinica.PARAMETRO_ID_HISTORIA_CLINICA, historiaClinica.getId()).getResultList();

        historiaClinica.setDetalleHistoriaClinica(detHis);

        return historiaClinica;
    }

    /**
     * Establece la consulta a manejar.
     * @param consulta 
     */
    public void setConsulta(Consulta consulta) {
        this.consulta = consulta;

        /*Si la cita ya esta tomada se cargan los datos de la misma.*/
        if (consulta.getEstado() == EstadoConsultaEnum.TOMADA) {
            List<OrdenMedica> list =
                    em.createNamedQuery(OrdenMedica.FIND_ORDENMEDICA_BY_ID_CONSULTA).
                    setParameter(OrdenMedica.PARAMETRO_ID_CONSULTA, consulta.getId()).
                    getResultList();

            if (list.isEmpty() == false) {
                orden = list.get(0);
            }

            if (orden != null) {
                List<DetalleOrdenMedica> lista = em.createNamedQuery(DetalleOrdenMedica.FIND_DETALLE_ORDEN_MEDICA_BY_ID_ORDEN_MEDICA).
                        setParameter(DetalleOrdenMedica.PARAMETRO_ID_ORDEN_MEDICA, orden.getId()).
                        getResultList();
                orden.setDetalleOrdenMedica(lista);
            }

            List<FormulaMedica> listaFor = em.createNamedQuery(FormulaMedica.FIND_FORMULA_MEDICA_BY_ID_CONSULTA).
                    setParameter(FormulaMedica.PARAMETRO_ID_CONSULTA, consulta.getId()).
                    getResultList();
            if (listaFor.isEmpty() == false) {
                formula = listaFor.get(0);
            }

            if (formula != null) {
                List<DetalleFormulaMedica> lista = em.createNamedQuery(DetalleFormulaMedica.FIND_DETALLE_FORMULA_MEDICA_BY_ID_FORMULA_MEDICA).
                        setParameter(DetalleFormulaMedica.PARAMETRO_ID_FORMULA_MEDICA, formula.getId()).
                        getResultList();
                formula.setDetallesFormulaMedica(lista);

            }

        }
            paciente = consulta.getPaciente();

    }
    
    public void ponerComentarioHistoriaClinica(String comentario){
        detalleHistoria=new DetalleHistoriaClinica();
        detalleHistoria.setComentario(comentario);
        detalleHistoria.setHistoria(historiaClinica);
        detalleHistoria.setConsulta(consulta);
    }
    
    public void terminar(){
        em.getTransaction().begin();
        
        
        
        consulta.setDetalleHistoriaClinica(detalleHistoria);
        consulta.setEstado(EstadoConsultaEnum.TOMADA);
        consulta.setFormulanMedica(formula);
        formula.setConsulta(consulta);
        consulta.setOrdenMedica(orden);
        orden.setConsulta(consulta);
        
        em.merge(consulta);
        em.flush();
        
        em.getTransaction().commit();
    }

    public Consulta getConsulta() {
        return consulta;
    }

    public Paciente getPaciente() {
        return paciente;
    }

    public FormulaMedica getFormula() {
        return formula;
    }

    public OrdenMedica getOrden() {
        return orden;
    }

    public DetalleHistoriaClinica getDetalleHistoria() {
        return detalleHistoria;
    }

    
    
    
    
}
